package com.edu.system.service.impl;

import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import com.edu.common.utils.uuid.Seq;
import com.edu.system.domain.TCanteen;
import com.edu.system.domain.dto.CanteenCnt;
import com.edu.system.domain.dto.CanteenCntDTO;
import com.edu.system.domain.dto.ChargeStatDTO;
import com.edu.system.mapper.TCanteenMapper;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Resource;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.edu.system.mapper.TChargeRecordMapper;
import com.edu.system.domain.TChargeRecord;
import com.edu.system.service.ITChargeRecordService;

/**
 * 消费记录Service业务层处理
 * 
 * @author xxxx
 * @date 2023-12-22
 */
@Service
public class TChargeRecordServiceImpl implements ITChargeRecordService 
{
    @Autowired
    private TChargeRecordMapper tChargeRecordMapper;
    @Resource
    private TCanteenMapper tCanteenMapper;

    /**
     * 查询消费记录
     * 
     * @param id 消费记录主键
     * @return 消费记录
     */
    @Override
    public TChargeRecord selectTChargeRecordById(Long id)
    {
        return tChargeRecordMapper.selectTChargeRecordById(id);
    }

    /**
     * 查询消费记录列表
     * 
     * @param tChargeRecord 消费记录
     * @return 消费记录
     */
    @Override
    public List<TChargeRecord> selectTChargeRecordList(TChargeRecord tChargeRecord)
    {
        List<TChargeRecord> tChargeRecords = tChargeRecordMapper.selectTChargeRecordList(tChargeRecord);

        if (CollectionUtils.isNotEmpty(tChargeRecords)){
            Set<Long> canteenIds = tChargeRecords.stream().map(TChargeRecord::getCanteenId).collect(Collectors.toSet());
            Map<Long, String> collect = tCanteenMapper.selectList(canteenIds)
                .stream()
                .collect(Collectors.toMap(TCanteen::getId, TCanteen::getName, (x, y) -> x));

            for (TChargeRecord t : tChargeRecords){
                t.setCanteenName(collect.getOrDefault(t.getCanteenId(), ""));
                t.setClassName(t.getGeneration() + "届" + t.getClassName());
            }
        }

        return tChargeRecords;
    }

    /**
     * 新增消费记录
     * 
     * @param tChargeRecord 消费记录
     * @return 结果
     */
    @Override
    public int insertTChargeRecord(TChargeRecord tChargeRecord)
    {
        return tChargeRecordMapper.insertTChargeRecord(tChargeRecord);
    }

    /**
     * 修改消费记录
     * 
     * @param tChargeRecord 消费记录
     * @return 结果
     */
    @Override
    public int updateTChargeRecord(TChargeRecord tChargeRecord)
    {
        return tChargeRecordMapper.updateTChargeRecord(tChargeRecord);
    }

    /**
     * 批量删除消费记录
     * 
     * @param ids 需要删除的消费记录主键
     * @return 结果
     */
    @Override
    public int deleteTChargeRecordByIds(Long[] ids)
    {
        return tChargeRecordMapper.deleteTChargeRecordByIds(ids);
    }

    /**
     * 删除消费记录信息
     * 
     * @param id 消费记录主键
     * @return 结果
     */
    @Override
    public int deleteTChargeRecordById(Long id)
    {
        return tChargeRecordMapper.deleteTChargeRecordById(id);
    }

    @Override
    public CanteenCntDTO countMealPersonNum(Long canteenId, Date start, Date end) {
        Map<String, Integer> m = tChargeRecordMapper.cntMeal(canteenId, start, end)
            .stream()
            .collect(Collectors.toMap(CanteenCnt::getChargeType, CanteenCnt::getCnt));

        return CanteenCntDTO.builder()
            .morningCnt(m.getOrDefault("早餐", 0))
            .noonCnt(m.getOrDefault("中餐", 0))
            .nightCnt(m.getOrDefault("晚餐", 0))
            .totalCnt(
                m.getOrDefault("早餐", 0) + m.getOrDefault("中餐", 0) + m.getOrDefault("晚餐", 0)
            )
            .build();
    }

    @Override
    public ChargeStatDTO getCountInfo() {
        Date date = new Date();
        // 当月刷卡数
        CanteenCntDTO month = this.countMealPersonNum(null, DateUtil.beginOfMonth(date), DateUtil.endOfMonth(date));
        // 当日刷卡数
        CanteenCntDTO today = this.countMealPersonNum(null, DateUtil.beginOfDay(date), DateUtil.endOfDay(date));
        // 昨日刷卡数
        DateTime yesDate = DateUtil.offsetDay(date, -1);
        CanteenCntDTO yes = this.countMealPersonNum(null, DateUtil.beginOfDay(yesDate), DateUtil.endOfDay(yesDate));

        return ChargeStatDTO.builder()
            .monthAmCnt(month.getMorningCnt())
            .monthNoonCnt(month.getNoonCnt())
            .monthPmCnt(month.getNightCnt())
            .morningCnt(today.getMorningCnt())
            .noonCnt(today.getNoonCnt())
            .nightCnt(today.getNightCnt())
            .percentMorning(
                Optional.ofNullable(yes.getMorningCnt())
                    .filter(a -> !a.equals(0))
                    .map(a -> Math.floorDiv((today.getMorningCnt() - a) * 100, a))
                    .orElseGet(() -> 0)
            )
            .percentNoon(
                Optional.ofNullable(yes.getNoonCnt())
                    .filter(a -> !a.equals(0))
                    .map(a -> Math.floorDiv((today.getNoonCnt() - a) * 100, a))
                    .orElseGet(() -> 0)
            )
            .percentNight(
                Optional.ofNullable(yes.getNightCnt())
                    .filter(a -> !a.equals(0))
                    .map(a -> Math.floorDiv((today.getNightCnt() - a) * 100, a))
                    .orElseGet(() -> 0)
            )
            .build();
    }


}
